package com.jbit.dm212.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.jbit.dm212.common.DateUtil;
import com.jbit.dm212.common.OrderUtil;
import com.jbit.dm212.common.UserUtil;
import com.jbit.dm212.entity.dto.DmOrderInfoDTO;
import com.jbit.dm212.entity.dto.DmOrderSearchDTO;
import com.jbit.dm212.entity.dto.DmSchedulerDTO;
import com.jbit.dm212.entity.dto.DmSchedulerSeatDTO;
import com.jbit.dm212.entity.po.*;
import com.jbit.dm212.entity.vo.DmItemSearchVO;
import com.jbit.dm212.entity.vo.DmOrderSearchVO;
import com.jbit.dm212.entity.vo.DmOrderVO;
import com.jbit.dm212.mapper.DmOrderMapper;
import com.jbit.dm212.service.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Service
public class DmOrderServiceImpl implements DmOrderService {
    @Resource
    private DmItemService itemService;
    @Resource
    private DmSchedulerSeatService schedulerSeatService;

    @Resource
    private DmLinkUserService linkUserService;

    @Resource
    private DmOrderMapper orderMapper;

    @Resource
    private DmOrderLinkUserService orderLinkUserService;
    @Override
    @Transactional
    public DmOrder createOrder(DmOrderVO orderVO) {
        DmOrder order = BeanUtil.toBean(orderVO,DmOrder.class);

        order.setOrderNo(OrderUtil.generateOrderNo());
        DmUser user = UserUtil.getUser();
        order.setUserId(user.getId());

        DmItem item = itemService.getItemById(order.getItemId());
        order.setItemName(item.getItemName());
        order.setOrderType(0);
        order.setInvoiceNo(OrderUtil.generateInvoiceNo());
        order.setInsuranceAmount(OrderUtil.getMoneyByInsurance(order.getIsNeedInsurance()));
        order.setCreatedTime(new Date());

        String [] linkIds = orderVO.getLinkIds().split(",");
        String [] seats = orderVO.getSeatPositions().split(",");

        List<DmSchedulerSeat> schedulerSeatList = OrderUtil.getSeatInfo(seats,order.getSchedulerId());
        List<DmSchedulerSeatDTO> schedulerSeatDTOList = schedulerSeatService.getSeatPrice(schedulerSeatList);


        List<DmLinkUser> linkUserList = linkUserService.getLinkUsers(linkIds);

        //设置订单商品总数量和总价格
        order.setTotalCount(linkIds.length);
        double totalPrice = schedulerSeatDTOList.stream().mapToDouble(seat->seat.getPrice()).sum();
        //总价为票价+保险
        order.setTotalAmount(totalPrice + order.getInsuranceAmount()*order.getTotalCount());

        orderMapper.insert(order);
        for (int i = 0; i < linkUserList.size(); i++) {
            DmLinkUser linkUser = linkUserList.get(i);
            DmSchedulerSeatDTO schedulerSeatDTO = schedulerSeatDTOList.get(i);
            DmOrderLinkUser orderLinkUser = new DmOrderLinkUser();
            orderLinkUser.setLinkUserId(linkUser.getId());
            orderLinkUser.setLinkUserName(linkUser.getName());
            orderLinkUser.setX(schedulerSeatDTO.getX());
            orderLinkUser.setY(schedulerSeatDTO.getY());
            orderLinkUser.setPrice(schedulerSeatDTO.getPrice());
            orderLinkUser.setCreatedTime(new Date());
            orderLinkUser.setOrderId(order.getId());

            DmSchedulerSeat schedulerSeat = new DmSchedulerSeat();
            schedulerSeat.setId(schedulerSeatDTO.getId());
            schedulerSeat.setOrderNo(order.getOrderNo());
            schedulerSeat.setStatus(2);
            schedulerSeatService.lockSeat(schedulerSeat);
            orderLinkUserService.save(orderLinkUser);
        }

        return order;
    }

    @Override
    public List<DmOrderSearchDTO> getOrderInfo(DmOrderSearchVO orderSearchVO) {
        DmUser user = UserUtil.getUser();
        String keyword = orderSearchVO.getKeyword();
        MPJLambdaWrapper<DmOrder> lambdaWrapper = new MPJLambdaWrapper<>();
        lambdaWrapper.select(DmOrder::getId,
                DmOrder::getOrderNo,
                DmOrder::getItemName,
                DmOrder::getOrderType,
                DmOrder::getTotalAmount);

        lambdaWrapper.selectAs(DmOrder::getTotalCount,"num");
        lambdaWrapper.selectAs(DmOrder::getCreatedTime,"sellTime");

        lambdaWrapper.eq(DmOrder::getUserId,user.getId());
        lambdaWrapper.eq(orderSearchVO.getOrderType() != 3,DmOrder::getOrderType,orderSearchVO.getOrderType());
        Calendar calendar = Calendar.getInstance();
        if (orderSearchVO.getOrderTime() == 1){
            calendar.add(Calendar.YEAR,-1);
        }else if(orderSearchVO.getOrderTime() == 2){
            calendar.add(Calendar.MONTH,-3);
        }
        lambdaWrapper.ge(orderSearchVO.getOrderTime() != 0,DmOrder::getCreatedTime,calendar.getTime());

        if (keyword != null && keyword.length() != 0){
            lambdaWrapper.like(DmOrder::getOrderNo,keyword);
            lambdaWrapper.like(DmOrder::getItemName,keyword);
//            lambdaWrapper.like(DmOrder::getItemId,keyword);
        }

        List<DmOrderSearchDTO> orderSearchDTOList = orderMapper.selectJoinList(DmOrderSearchDTO.class,lambdaWrapper);

        orderSearchDTOList.forEach(order->{
            double unitPrice = order.getTotalAmount() / order.getNum();
            order.setUnitPrice(unitPrice);
        });

        return orderSearchDTOList;
    }

    @Override
    public DmOrderInfoDTO getOrderInfoByOrderNo(String orderNo) {
        MPJLambdaWrapper<DmOrder> lambdaWrapper = new MPJLambdaWrapper<>();
        lambdaWrapper.select(DmOrder::getOrderNo,DmOrder::getItemName,DmOrder::getTotalAmount);
        lambdaWrapper.selectAs(DmOrder::getTotalCount,"seatCount");
        lambdaWrapper.eq(DmOrder::getOrderNo,orderNo);
        return orderMapper.selectJoinOne(DmOrderInfoDTO.class,lambdaWrapper);
    }

    @Override
    public boolean updateOrderType(DmOrder order) {
        LambdaUpdateWrapper<DmOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(DmOrder::getOrderType,order.getOrderType())
                .set(DmOrder::getAliTradeNo,order.getAliTradeNo())
                .set(DmOrder::getPayType,2)
                .set(DmOrder::getUpdatedTime,order.getUpdatedTime() == null ? Calendar.getInstance().getTime() : order.getUpdatedTime());
        updateWrapper.eq(DmOrder::getOrderNo,order.getOrderNo());
        return orderMapper.update(null,updateWrapper) == 1;
    }
}
